home *** CD-ROM | disk | FTP | other *** search
/ IRIX 6.3 Development Libraries / SGI IRIX 6.3 Development Libraries.iso / dist6.3 / gl_dev.idb / usr / share / src / OpenGL / toolkits / libtk / window.c.z / window.c
Encoding:
C/C++ Source or Header  |  1996-12-06  |  20.6 KB  |  648 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include "tk.h"
  5. #include "private.h"
  6.  
  7. /******************************************************************************/
  8.  
  9. Display *xDisplay = 0;
  10. int xScreen = 0; 
  11. Window wRoot = 0;
  12. Atom deleteWindowAtom;
  13. WINDOW_REC w = {
  14.     0, 0, 300, 300, TK_RGB|TK_SINGLE|TK_DIRECT, TK_MINIMUM_CRITERIA
  15. };
  16. float colorMaps[] = {
  17.     0.000000, 1.000000, 0.000000, 1.000000, 0.000000, 1.000000, 
  18.     0.000000, 1.000000, 0.333333, 0.776471, 0.443137, 0.556863, 
  19.     0.443137, 0.556863, 0.219608, 0.666667, 0.666667, 0.333333, 
  20.     0.666667, 0.333333, 0.666667, 0.333333, 0.666667, 0.333333, 
  21.     0.666667, 0.333333, 0.666667, 0.333333, 0.666667, 0.333333, 
  22.     0.666667, 0.333333, 0.039216, 0.078431, 0.117647, 0.156863, 
  23.     0.200000, 0.239216, 0.278431, 0.317647, 0.356863, 0.400000, 
  24.     0.439216, 0.478431, 0.517647, 0.556863, 0.600000, 0.639216, 
  25.     0.678431, 0.717647, 0.756863, 0.800000, 0.839216, 0.878431, 
  26.     0.917647, 0.956863, 0.000000, 0.000000, 0.000000, 0.000000, 
  27.     0.000000, 0.000000, 0.000000, 0.000000, 0.247059, 0.247059, 
  28.     0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 
  29.     0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 
  30.     0.498039, 0.498039, 0.749020, 0.749020, 0.749020, 0.749020, 
  31.     0.749020, 0.749020, 0.749020, 0.749020, 1.000000, 1.000000, 
  32.     1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 
  33.     0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 
  34.     0.000000, 0.000000, 0.247059, 0.247059, 0.247059, 0.247059, 
  35.     0.247059, 0.247059, 0.247059, 0.247059, 0.498039, 0.498039, 
  36.     0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 
  37.     0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 
  38.     0.749020, 0.749020, 1.000000, 1.000000, 1.000000, 1.000000, 
  39.     1.000000, 1.000000, 1.000000, 1.000000, 0.000000, 0.000000, 
  40.     0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 
  41.     0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 
  42.     0.247059, 0.247059, 0.498039, 0.498039, 0.498039, 0.498039, 
  43.     0.498039, 0.498039, 0.498039, 0.498039, 0.749020, 0.749020, 
  44.     0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 
  45.     1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 
  46.     1.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 
  47.     0.000000, 0.000000, 0.000000, 0.000000, 0.247059, 0.247059, 
  48.     0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 
  49.     0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 
  50.     0.498039, 0.498039, 0.749020, 0.749020, 0.749020, 0.749020, 
  51.     0.749020, 0.749020, 0.749020, 0.749020, 1.000000, 1.000000, 
  52.     1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 
  53.     0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 
  54.     0.000000, 0.000000, 0.247059, 0.247059, 0.247059, 0.247059, 
  55.     0.247059, 0.247059, 0.247059, 0.247059, 0.498039, 0.498039, 
  56.     0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 
  57.     0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 
  58.     0.749020, 0.749020, 1.000000, 1.000000, 1.000000, 1.000000, 
  59.     1.000000, 1.000000, 1.000000, 1.000000, 0.000000, 0.000000, 
  60.     1.000000, 1.000000, 0.000000, 0.000000, 1.000000, 1.000000, 
  61.     0.333333, 0.443137, 0.776471, 0.556863, 0.443137, 0.219608, 
  62.     0.556863, 0.666667, 0.666667, 0.333333, 0.666667, 0.333333, 
  63.     0.666667, 0.333333, 0.666667, 0.333333, 0.666667, 0.333333, 
  64.     0.666667, 0.333333, 0.666667, 0.333333, 0.666667, 0.333333, 
  65.     0.039216, 0.078431, 0.117647, 0.156863, 0.200000, 0.239216, 
  66.     0.278431, 0.317647, 0.356863, 0.400000, 0.439216, 0.478431, 
  67.     0.517647, 0.556863, 0.600000, 0.639216, 0.678431, 0.717647, 
  68.     0.756863, 0.800000, 0.839216, 0.878431, 0.917647, 0.956863, 
  69.     0.000000, 0.141176, 0.282353, 0.427451, 0.568627, 0.713726, 
  70.     0.854902, 1.000000, 0.000000, 0.141176, 0.282353, 0.427451, 
  71.     0.568627, 0.713726, 0.854902, 1.000000, 0.000000, 0.141176, 
  72.     0.282353, 0.427451, 0.568627, 0.713726, 0.854902, 1.000000, 
  73.     0.000000, 0.141176, 0.282353, 0.427451, 0.568627, 0.713726, 
  74.     0.854902, 1.000000, 0.000000, 0.141176, 0.282353, 0.427451, 
  75.     0.568627, 0.713726, 0.854902, 1.000000, 0.000000, 0.141176, 
  76.     0.282353, 0.427451, 0.568627, 0.713726, 0.854902, 1.000000, 
  77.     0.000000, 0.141176, 0.282353, 0.427451, 0.568627, 0.713726, 
  78.     0.854902, 1.000000, 0.000000, 0.141176, 0.282353, 0.427451, 
  79.     0.568627, 0.713726, 0.854902, 1.000000, 0.000000, 0.141176, 
  80.     0.282353, 0.427451, 0.568627, 0.713726, 0.854902, 1.000000, 
  81.     0.000000, 0.141176, 0.282353, 0.427451, 0.568627, 0.713726, 
  82.     0.854902, 1.000000, 0.000000, 0.141176, 0.282353, 0.427451, 
  83.     0.568627, 0.713726, 0.854902, 1.000000, 0.000000, 0.141176, 
  84.     0.282353, 0.427451, 0.568627, 0.713726, 0.854902, 1.000000, 
  85.     0.000000, 0.141176, 0.282353, 0.427451, 0.568627, 0.713726, 
  86.     0.854902, 1.000000, 0.000000, 0.141176, 0.282353, 0.427451, 
  87.     0.568627, 0.713726, 0.854902, 1.000000, 0.000000, 0.141176, 
  88.     0.282353, 0.427451, 0.568627, 0.713726, 0.854902, 1.000000, 
  89.     0.000000, 0.141176, 0.282353, 0.427451, 0.568627, 0.713726, 
  90.     0.854902, 1.000000, 0.000000, 0.141176, 0.282353, 0.427451, 
  91.     0.568627, 0.713726, 0.854902, 1.000000, 0.000000, 0.141176, 
  92.     0.282353, 0.427451, 0.568627, 0.713726, 0.854902, 1.000000, 
  93.     0.000000, 0.141176, 0.282353, 0.427451, 0.568627, 0.713726, 
  94.     0.854902, 1.000000, 0.000000, 0.141176, 0.282353, 0.427451, 
  95.     0.568627, 0.713726, 0.854902, 1.000000, 0.000000, 0.141176, 
  96.     0.282353, 0.427451, 0.568627, 0.713726, 0.854902, 1.000000, 
  97.     0.000000, 0.141176, 0.282353, 0.427451, 0.568627, 0.713726, 
  98.     0.854902, 1.000000, 0.000000, 0.141176, 0.282353, 0.427451, 
  99.     0.568627, 0.713726, 0.854902, 1.000000, 0.000000, 0.141176, 
  100.     0.282353, 0.427451, 0.568627, 0.713726, 0.854902, 1.000000, 
  101.     0.000000, 0.141176, 0.282353, 0.427451, 0.568627, 0.713726, 
  102.     0.854902, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 
  103.     1.000000, 1.000000, 1.000000, 1.000000, 0.333333, 0.443137, 
  104.     0.443137, 0.219608, 0.776471, 0.556863, 0.556863, 0.666667, 
  105.     0.666667, 0.333333, 0.666667, 0.333333, 0.666667, 0.333333, 
  106.     0.666667, 0.333333, 0.666667, 0.333333, 0.666667, 0.333333, 
  107.     0.666667, 0.333333, 0.666667, 0.333333, 0.039216, 0.078431, 
  108.     0.117647, 0.156863, 0.200000, 0.239216, 0.278431, 0.317647, 
  109.     0.356863, 0.400000, 0.439216, 0.478431, 0.517647, 0.556863, 
  110.     0.600000, 0.639216, 0.678431, 0.717647, 0.756863, 0.800000, 
  111.     0.839216, 0.878431, 0.917647, 0.956863, 0.000000, 0.000000, 
  112.     0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 
  113.     0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 
  114.     0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 
  115.     0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 
  116.     0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 
  117.     0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 
  118.     0.000000, 0.000000, 0.247059, 0.247059, 0.247059, 0.247059, 
  119.     0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 
  120.     0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 
  121.     0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 
  122.     0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 
  123.     0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 
  124.     0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 
  125.     0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 
  126.     0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 
  127.     0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 
  128.     0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 
  129.     0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 
  130.     0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 
  131.     0.498039, 0.498039, 0.498039, 0.498039, 0.749020, 0.749020, 
  132.     0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 
  133.     0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 
  134.     0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 
  135.     0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 
  136.     0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 
  137.     0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 
  138.     0.749020, 0.749020, 1.000000, 1.000000, 1.000000, 1.000000, 
  139.     1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 
  140.     1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 
  141.     1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 
  142.     1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 
  143.     1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 
  144.     1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 
  145. };
  146. float tkRGBMap[8][3] = {
  147.     {
  148.     0, 0, 0
  149.     },
  150.     {
  151.     1, 0, 0
  152.     },
  153.     {
  154.     0, 1, 0
  155.     },
  156.     {
  157.     1, 1, 0
  158.     },
  159.     {
  160.     0, 0, 1
  161.     },
  162.     {
  163.     1, 0, 1
  164.     },
  165.     {
  166.     0, 1, 1
  167.     },
  168.     {
  169.     1, 1, 1
  170.     }
  171. };
  172.  
  173. /******************************************************************************/
  174.  
  175. void tkCloseWindow(void)
  176. {
  177.  
  178.     if (xDisplay) {
  179.     cursorNum = 0;
  180.  
  181.     ExposeFunc = 0;
  182.     ReshapeFunc = 0;
  183.     IdleFunc = 0;
  184.     DisplayFunc = 0;
  185.     KeyDownFunc = 0;
  186.     MouseDownFunc = 0;
  187.     MouseUpFunc = 0;
  188.     MouseMoveFunc = 0;
  189.  
  190.     glFlush();
  191.     glFinish();
  192.     if (TK_HAS_OVERLAY(w.type)) {
  193.         XDestroyWindow(xDisplay, w.wOverlay);
  194.         glXDestroyContext(xDisplay, w.cOverlay);
  195.         XFreeColormap(xDisplay, w.cMapOverlay);
  196.         XFree((char *)w.vInfoOverlay);
  197.     }
  198.     XDestroyWindow(xDisplay, w.wMain);
  199.     glXDestroyContext(xDisplay, w.cMain);
  200.     XFreeColormap(xDisplay, w.cMapMain);
  201.     XFree((char *)w.vInfoMain);
  202.     XCloseDisplay(xDisplay);
  203.     xDisplay = 0;
  204.     }
  205. }
  206.  
  207. /******************************************************************************/
  208.  
  209. static int ErrorHandler(Display *xDisplay, XErrorEvent *event)
  210. {
  211.     char buf[80];
  212.  
  213.     printf("\nReceived X error!\n");
  214.     printf("\tError code   : %d\n", event->error_code);
  215.     printf("\tRequest code : %d\n", event->request_code);
  216.     printf("\tMinor code   : %d\n\n", event->minor_code);
  217.     XGetErrorText(xDisplay, event->error_code, buf, 80);
  218.     printf("\tError text : '%s'\n\n", buf);
  219.     return 0;
  220. }
  221.  
  222. /******************************************************************************/
  223.  
  224. void tkInitDisplayMode(GLenum type)
  225. {
  226.  
  227.     w.type = type;
  228. }
  229.  
  230. /******************************************************************************/
  231.  
  232. void tkInitDisplayModePolicy(GLenum type)
  233. {
  234.  
  235.     w.dmPolicy = type;
  236. }
  237.  
  238. /******************************************************************************/
  239.  
  240. GLenum tkInitDisplayModeID(GLint id)
  241. {
  242.     XVisualInfo sampleVis;
  243.     int nvis;
  244.  
  245.     if (!xDisplay && !tkInitDisplay()) return(GL_FALSE);
  246.  
  247.     sampleVis.visualid = id;
  248.     w.vInfoMain = XGetVisualInfo(xDisplay, VisualIDMask, &sampleVis, &nvis);
  249.  
  250.     if (w.vInfoMain) 
  251.         return GL_TRUE;
  252.     else
  253.         return GL_FALSE;
  254. }
  255.  
  256. /******************************************************************************/
  257.  
  258. void tkInitPosition(int x, int y, int width, int height)
  259. {
  260.  
  261.     w.x = x;
  262.     w.y = y;
  263.     w.w = width;
  264.     w.h = height;
  265. }
  266.  
  267. /******************************************************************************/
  268.  
  269. static XVisualInfo *FindBestMainVisual(GLenum type)
  270. {
  271.     int list[32], i;
  272.  
  273.     i = 0;
  274.  
  275.     list[i++] = GLX_LEVEL;
  276.     list[i++] = 0;
  277.  
  278.     if (TK_IS_DOUBLE(type)) {
  279.     list[i++] = GLX_DOUBLEBUFFER;
  280.     }
  281.  
  282.     if (TK_IS_RGB(type)) {
  283.     list[i++] = GLX_RGBA;
  284.     list[i++] = GLX_RED_SIZE;
  285.     list[i++] = 1;
  286.     list[i++] = GLX_GREEN_SIZE;
  287.     list[i++] = 1;
  288.     list[i++] = GLX_BLUE_SIZE;
  289.     list[i++] = 1;
  290.     if (TK_HAS_ALPHA(type)) {
  291.         list[i++] = GLX_ALPHA_SIZE;
  292.         list[i++] = 1;
  293.     }
  294.     if (TK_HAS_ACCUM(type)) {
  295.         list[i++] = GLX_ACCUM_RED_SIZE;
  296.         list[i++] = 1;
  297.         list[i++] = GLX_ACCUM_GREEN_SIZE;
  298.         list[i++] = 1;
  299.         list[i++] = GLX_ACCUM_BLUE_SIZE;
  300.         list[i++] = 1;
  301.         if (TK_HAS_ALPHA(type)) {
  302.         list[i++] = GLX_ACCUM_ALPHA_SIZE;
  303.         list[i++] = 1;
  304.         }
  305.     }
  306.     } else if (TK_IS_INDEX(type)) {
  307.     list[i++] = GLX_BUFFER_SIZE;
  308.     list[i++] = 1;
  309.     }
  310.  
  311.     if (TK_HAS_DEPTH(type)) {
  312.     list[i++] = GLX_DEPTH_SIZE;
  313.     list[i++] = 1;
  314.     }
  315.  
  316.     if (TK_HAS_STENCIL(type)) {
  317.     list[i++] = GLX_STENCIL_SIZE;
  318.     list[i++] = 1;
  319.     }
  320.  
  321.     list[i] = (int)None;
  322.  
  323.     return glXChooseVisual(xDisplay, xScreen, list);
  324. }
  325.  
  326. /******************************************************************************/
  327.  
  328. static XVisualInfo *FindExactMainVisual(GLenum type)
  329. {
  330.     int i, nvis, val, rval, gval, bval, aval;
  331.     XVisualInfo *vis_list, *this_vis, *best_vis, sampleVis;
  332.     int this_score, best_score;
  333.  
  334.     /* Get list of visuals for this screen */
  335.     sampleVis.screen = xScreen;
  336.     vis_list = XGetVisualInfo( xDisplay, VisualScreenMask, &sampleVis, &nvis);
  337.  
  338.     /* 
  339.      * Loop through the visuals; find first one that matches the attr 
  340.      * specified in type
  341.      */
  342.     best_score = -1; best_vis = NULL;
  343.     for ( i = 0; i < nvis; i++ ) {
  344.       this_vis = &vis_list[i];
  345.  
  346.       /* Visual must be supported by GLX */
  347.       if ( glXGetConfig(xDisplay, this_vis, GLX_USE_GL, &val) ) continue;
  348.       if ( !val ) continue;
  349.  
  350.       /* Visual must be in main planes which is level 0 */
  351.       glXGetConfig(xDisplay, this_vis, GLX_LEVEL, &val);
  352.       if ( val != 0 ) continue;
  353.  
  354.       /* Color Index or RGBA? It must match the requested value */
  355.       glXGetConfig(xDisplay, this_vis, GLX_RGBA, &val);
  356.       if ( TK_IS_RGB(type) && !val ) continue;
  357.       if ( TK_IS_INDEX(type) && val ) continue;
  358.  
  359.       /* Double buffered or Single buffered? */
  360.       glXGetConfig( xDisplay, this_vis, GLX_DOUBLEBUFFER, &val);
  361.       if ( TK_IS_DOUBLE(type) && !val ) continue;
  362.       if ( TK_IS_SINGLE(type) && val ) continue;
  363.  
  364.       /* If accum requested then accum rgb size must be > 0 */
  365.       /* If alpha requested then alpha size must be > 0 */
  366.       /* if accum & alpha requested then accum alpha size must be > 0 */
  367.       if ( TK_IS_RGB(type) ) {
  368.         glXGetConfig(xDisplay, this_vis, GLX_ACCUM_RED_SIZE, &rval);
  369.         glXGetConfig(xDisplay, this_vis, GLX_ACCUM_GREEN_SIZE, &gval);
  370.         glXGetConfig(xDisplay, this_vis, GLX_ACCUM_BLUE_SIZE, &bval);
  371.         glXGetConfig(xDisplay, this_vis, GLX_ACCUM_ALPHA_SIZE, &aval);
  372.         if ( TK_HAS_ACCUM(type) ) {
  373.             if ( rval <= 0 || gval <= 0 || bval <= 0 ) continue;
  374.         } else {
  375.             if ( rval > 0 || gval > 0 || bval > 0 || aval > 0 ) continue;
  376.         }
  377.  
  378.         glXGetConfig(xDisplay, this_vis, GLX_ALPHA_SIZE, &val);
  379.         if ( TK_HAS_ALPHA(type) ) {
  380.             if ( val <= 0 ) continue;
  381.             if ( TK_HAS_ACCUM(type) && aval <= 0 ) continue;
  382.         } else {
  383.             if ( val > 0 ) continue;
  384.         }
  385.  
  386.       }
  387.  
  388.       /* Check depth buffer */
  389.       glXGetConfig(xDisplay, this_vis, GLX_DEPTH_SIZE, &val);
  390.       if ( TK_HAS_DEPTH(type) ) {
  391.             if ( val <= 0 ) continue;
  392.       } else {
  393.             if ( val > 0 ) continue;
  394.       }
  395.  
  396.       /* Check stencil buffer */
  397.       glXGetConfig( xDisplay, this_vis, GLX_STENCIL_SIZE, &val);
  398.       if ( TK_HAS_STENCIL(type) ) {
  399.             if ( val <= 0 ) continue;
  400.       } else {
  401.             if ( val > 0 ) continue;
  402.       }
  403.  
  404.       glXGetConfig(xDisplay, this_vis, GLX_BUFFER_SIZE, &this_score);
  405.  
  406.       if (this_score > best_score ) {
  407.           best_score = this_score;
  408.           best_vis = this_vis;
  409.       }
  410.  
  411.     }
  412.  
  413.     if ( best_vis ) {
  414.         sampleVis.visualid = best_vis->visualid;
  415.         sampleVis.screen = xScreen;
  416.         if ( nvis > 0 ) XFree(vis_list);
  417.         return XGetVisualInfo(xDisplay, VisualIDMask|VisualScreenMask, 
  418.               &sampleVis, &nvis);
  419.     } else {
  420.         if ( nvis > 0 ) XFree(vis_list);
  421.         return None;
  422.     }
  423.  
  424. }
  425.  
  426. static XVisualInfo *FindOverlayVisual(void)
  427. {
  428.     int list[3];
  429.  
  430.     list[0] = GLX_LEVEL;
  431.     list[1] = 1;
  432.     list[2] = (int)None;
  433.  
  434.     return glXChooseVisual(xDisplay, xScreen, list);
  435. }
  436.  
  437. static GLenum GetMainWindowType(XVisualInfo *vi)
  438. {
  439.     GLenum mask;
  440.     int x, y, z;
  441.  
  442.     mask = 0;
  443.  
  444.     glXGetConfig(xDisplay, vi, GLX_DOUBLEBUFFER, &x);
  445.     if (x) {
  446.     mask |= TK_DOUBLE;
  447.     } else {
  448.     mask |= TK_SINGLE;
  449.     }
  450.  
  451.     glXGetConfig(xDisplay, vi, GLX_RGBA, &x);
  452.     if (x) {
  453.     mask |= TK_RGB;
  454.     glXGetConfig(xDisplay, vi, GLX_ALPHA_SIZE, &x);
  455.     if (x > 0) {
  456.         mask |= TK_ALPHA;
  457.     }
  458.     glXGetConfig(xDisplay, vi, GLX_ACCUM_RED_SIZE, &x);
  459.     glXGetConfig(xDisplay, vi, GLX_ACCUM_GREEN_SIZE, &y);
  460.     glXGetConfig(xDisplay, vi, GLX_ACCUM_BLUE_SIZE, &z);
  461.     if (x > 0 && y > 0 && z > 0) {
  462.         mask |= TK_ACCUM;
  463.     }
  464.     } else {
  465.     mask |= TK_INDEX;
  466.     }
  467.  
  468.     glXGetConfig(xDisplay, vi, GLX_DEPTH_SIZE, &x);
  469.     if (x > 0) {
  470.     mask |= TK_DEPTH;
  471.     }
  472.  
  473.     glXGetConfig(xDisplay, vi, GLX_STENCIL_SIZE, &x);
  474.     if (x > 0) {
  475.     mask |= TK_STENCIL;
  476.     }
  477.  
  478.     if (glXIsDirect(xDisplay, w.cMain)) {
  479.     mask |= TK_DIRECT;
  480.     } else {
  481.     mask |= TK_INDIRECT;
  482.     }
  483.  
  484.     return mask;
  485. }
  486.  
  487. static int WaitForMainWindow(Display *d, XEvent *e, char *arg)
  488. {
  489.  
  490.     if (e->type == MapNotify && e->xmap.window == w.wMain) {
  491.     return GL_TRUE;
  492.     } else {
  493.     return GL_FALSE;
  494.     }
  495. }
  496.  
  497. static int WaitForOverlayWindow(Display *d, XEvent *e, char *arg)
  498. {
  499.  
  500.     if (e->type == MapNotify && e->xmap.window == w.wOverlay) {
  501.     return GL_TRUE;
  502.     } else {
  503.     return GL_FALSE;
  504.     }
  505. }
  506.  
  507. GLenum tkInitDisplay(void)
  508. {
  509.     int erb, evb;
  510.  
  511.     xDisplay = XOpenDisplay(0);
  512.     if (!xDisplay) {
  513.        fprintf(stderr, "Can't connect to xDisplay!\n");
  514.        return GL_FALSE;
  515.     }
  516.     if (!glXQueryExtension(xDisplay, &erb, &evb)) {
  517.        fprintf(stderr, "No glx extension!\n");
  518.        return GL_FALSE;
  519.     }
  520.     xScreen = DefaultScreen(xDisplay);
  521.     wRoot = RootWindow(xDisplay, xScreen);
  522.     XSetErrorHandler(ErrorHandler);
  523.     return(GL_TRUE);
  524. }
  525.  
  526. GLenum tkInitWindow(char *title)
  527. {
  528.     XSetWindowAttributes wa;
  529.     XTextProperty tp;
  530.     XSizeHints sh;
  531.     XEvent e;
  532.     GLenum overlayFlag;
  533.  
  534.     if (!xDisplay && !tkInitDisplay()) return(GL_FALSE);
  535.  
  536.     if (TK_HAS_OVERLAY(w.type)) {
  537.     overlayFlag = GL_TRUE;
  538.     } else {
  539.     overlayFlag = GL_FALSE;
  540.     }
  541.     w.type &= ~TK_OVERLAY;
  542.  
  543.     if (w.dmPolicy == TK_MINIMUM_CRITERIA)
  544.         w.vInfoMain = FindBestMainVisual(w.type);
  545.     else if (w.dmPolicy == TK_EXACT_MATCH)
  546.         w.vInfoMain = FindExactMainVisual(w.type);
  547.     if (!w.vInfoMain) {
  548.     fprintf(stderr, "Window type not found!\n");
  549.     return GL_FALSE;
  550.     }
  551.  
  552.     w.cMain = glXCreateContext(xDisplay, w.vInfoMain, None,
  553.                    (TK_IS_DIRECT(w.type))?GL_TRUE:GL_FALSE);
  554.     if (!w.cMain) {
  555.     fprintf(stderr, "Can't create a context!\n");
  556.     return GL_FALSE;
  557.     }
  558.  
  559.     w.type = GetMainWindowType(w.vInfoMain);
  560.  
  561.     if (TK_IS_INDEX(w.type)) {
  562.     if (w.vInfoMain->class != StaticColor &&
  563.         w.vInfoMain->class != StaticGray) {
  564.         w.cMapMain = XCreateColormap(xDisplay, wRoot, w.vInfoMain->visual,
  565.                          AllocAll);
  566.     } else {
  567.         w.cMapMain = XCreateColormap(xDisplay, wRoot, w.vInfoMain->visual,
  568.                          AllocNone);
  569.     }
  570.     } else {
  571.     w.cMapMain = XCreateColormap(xDisplay, wRoot, w.vInfoMain->visual,
  572.                      AllocNone);
  573.     }
  574.     tkSetRGBMap(256, colorMaps);
  575.     wa.colormap = w.cMapMain;
  576.     wa.background_pixmap = None;
  577.     wa.border_pixel = 0;
  578.     wa.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask |
  579.             ButtonPressMask | ButtonReleaseMask | PointerMotionMask;
  580.     w.wMain = XCreateWindow(xDisplay, wRoot, w.x, w.y, w.w, w.h, 0,
  581.                 w.vInfoMain->depth, InputOutput,
  582.                 w.vInfoMain->visual,
  583.                 CWBackPixmap|CWBorderPixel|CWEventMask|CWColormap,
  584.                 &wa);
  585.  
  586.     XStringListToTextProperty(&title, 1, &tp);
  587.     sh.flags = USPosition | USSize;
  588.     XSetWMProperties(xDisplay, w.wMain, &tp, &tp, 0, 0, &sh, 0, 0);
  589.     deleteWindowAtom = XInternAtom(xDisplay, "WM_DELETE_WINDOW", False);
  590.     XSetWMProtocols(xDisplay, w.wMain, &deleteWindowAtom, 1);
  591.     XMapWindow(xDisplay, w.wMain);
  592.     drawAllowFlag = GL_FALSE;
  593.     XIfEvent(xDisplay, &e, WaitForMainWindow, 0);
  594.  
  595.     if (overlayFlag == GL_TRUE) {
  596.     w.vInfoOverlay = FindOverlayVisual();
  597.     if (w.vInfoOverlay) {
  598.         w.cOverlay = glXCreateContext(xDisplay, w.vInfoOverlay, None,
  599.                       GL_TRUE);
  600.         w.cMapOverlay = XCreateColormap(xDisplay, wRoot,
  601.                         w.vInfoOverlay->visual, AllocNone);
  602.         tkSetOverlayMap(256, colorMaps);
  603.         wa.colormap = w.cMapOverlay;
  604.         wa.background_pixmap = None;
  605.         wa.border_pixel = 0;
  606.         w.wOverlay = XCreateWindow(xDisplay, w.wMain, 0, 0, w.w, w.h, 0,
  607.                        w.vInfoOverlay->depth, InputOutput,
  608.                        w.vInfoOverlay->visual,
  609.                        CWBackPixmap|CWBorderPixel|CWColormap,
  610.                        &wa);
  611.         XMapWindow(xDisplay, w.wOverlay);
  612.         XSetWMColormapWindows(xDisplay, w.wMain, &w.wOverlay, 1);
  613.         w.type |= TK_OVERLAY;
  614.     } else {
  615.         fprintf(stderr, "Can't create a overlay plane!\n");
  616.     }
  617.     }
  618.  
  619.     if (!glXMakeCurrent(xDisplay, w.wMain, w.cMain)) {
  620.     fprintf(stderr, "Can't make window current drawable!\n");
  621.     return GL_FALSE;
  622.     }
  623.     XFlush(xDisplay);
  624.  
  625.     return GL_TRUE;
  626. }
  627.  
  628. /******************************************************************************/
  629.  
  630. void tkQuit(void)
  631. {
  632.  
  633.     tkCloseWindow();
  634.     exit(0);
  635. }
  636.  
  637. /******************************************************************************/
  638.  
  639. void tkSwapBuffers(void)
  640. {
  641.  
  642.     if (xDisplay) {
  643.     glXSwapBuffers(xDisplay, w.wMain);
  644.     }
  645. }
  646.  
  647. /******************************************************************************/
  648.